﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;

namespace NFinal.Middleware.UnZip
{
    public class HttpResponse
    {
        public HttpResponse()
        {
            this.headers = new Dictionary<string, string[]>();
        }
        public Dictionary<string, string[]> headers;
        public int statusCode;
        public Stream body;
    }
    
    public class UnZipServer
    {
        public static SortedList<string, HttpResponse> staticFiles = new SortedList<string, HttpResponse>();
        public static SortedList<string, Stream> staticFilesStream = new SortedList<string, Stream>();
        public static Dictionary<string, string> contentTypes = new Dictionary<string, string>();
        public static void InitDefaultContentTypes()
        {
            contentTypes.Add(".json","application/json; charset=utf-8");
            contentTypes.Add(".css", "text/css; charset=utf-8");
            contentTypes.Add(".jpg", "application/x-jpg");
            contentTypes.Add(".jpeg", "image/jpeg");
            contentTypes.Add(".png", "image/png");
            contentTypes.Add(".html","text/html; charset=utf-8");
            contentTypes.Add(".js", "application/x-javascript");
            contentTypes.Add(".ico", "image/x-icon");

        }
        public static HttpResponse GetResponse(string relativePath)
        {
            HttpResponse httpResponse = null;
            if (staticFiles.TryGetValue(relativePath, out httpResponse))
            {
                return httpResponse;
            }
            else
            {
                httpResponse = new HttpResponse();
                httpResponse.headers.Add("Content-Type", new string[] { "text/html; charset=utf-8" });
                httpResponse.statusCode = 403;
                return httpResponse;
            }
        }
        public static void GetAllStream(Stream ZipStream,string requestPrefix, string password)
        {
            if (!string.IsNullOrEmpty(requestPrefix))
            {
                if (requestPrefix[0] != '/')
                {
                    requestPrefix = "/" + requestPrefix;
                }
            }
            MemoryStream stream = null;
            ZipStream.Seek(0, SeekOrigin.Begin);
            using (ZipInputStream s = new ZipInputStream(ZipStream))
            {
                s.Password = password;
                ZipEntry zipEntry;
                string key = null;
                HttpResponse httpResponse = null;
                while ((zipEntry = s.GetNextEntry()) != null)
                {
                    if (zipEntry.IsFile)
                    {
                        string extension = Path.GetExtension(zipEntry.Name);
                        string contentType = null;
                        httpResponse = new HttpResponse();
                        if (contentTypes.TryGetValue(extension, out contentType))
                        {
                            httpResponse.headers.Add("Content-Type", new string[] { contentType });
                            httpResponse.statusCode = 200;
                        }
                        else
                        {
                            httpResponse.headers.Add("Content-Type", new string[] { "text/html; charset=utf-8" });
                            httpResponse.statusCode = 404;
                        }
                        if (zipEntry.Size > 0)
                        {
                            stream = new MemoryStream((int)zipEntry.Size);
                        }
                        else
                        {
                            stream = new MemoryStream();
                        }
                        s.CopyTo(stream);
                        key = requestPrefix+ "/" + zipEntry.Name.TrimEnd('/');
                        httpResponse.body = stream;
                        staticFiles.Add(key, httpResponse);
                    }
                }
            }
        }
    }
}
